
#ifndef __SSPROTO_VARIANT_H
#define __SSPROTO_VARIANT_H 1

#include "extdef.h"

#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>

namespace qb {
namespace proto{

#if defined(WIN32) || defined(_WINDOWS)

typedef unsigned char       uint8_t;
typedef signed char         int8_t;
typedef unsigned short      uint16_t;
typedef short               int16_t;
typedef unsigned int        uint32_t;
typedef int                 int32_t;
typedef unsigned long long  uint64_t;
typedef long long           int64_t;

#else
#include <stdint.h>
typedef uint8_t uint8_t ;
typedef int8_t  int8_t ;
typedef uint16_t uint16_t ;
typedef int16_t  int16_t ;
typedef uint32_t uint32_t ;
typedef int32_t  int32_t ;
typedef uint64_t uint64_t ;
typedef int64_t  int64_t ; 

#endif

class  Variant ;
class  VariantRaw ;
class  VariantMap ;
class  VariantList ;

/*
    代替Raw
*/
class SSPROTOAPI VariantRaw{
public:
    void * Data ;
    uint32_t Length ;

    VariantRaw() ;
    VariantRaw(const VariantRaw& raw) ;
    ~VariantRaw() ;

    bool Copy(const VariantRaw& raw) ;
    bool Copy(const void * buffer , size_t buflen) ;

    void Ref(const VariantRaw& raw) ;
    void Clear() ;

    VariantRaw& operator=(const VariantRaw& raw) ;
    inline bool Owned() const {return owned_ ;}
private:
    bool owned_ ;       //是否由这个类自动释放。
} ;

/*
    替代list
*/
class SSPROTOAPI VariantList{
public:
    VariantList() ;
    VariantList(const VariantList& list) ;

    virtual ~VariantList() ;
    inline size_t size() const {return size_ ;}

	// 将本身编码成新编码的table格式,返回新编码的大小
	// 如果不符合list<map>模式,那么会返回0
	// 如果尺寸不够,会返回负值,绝对值是需要的尺寸
	int encodeAsTable(char* buf, int capcity)const;

    void push_back(const Variant& var) ;

    VariantMap* add_map() ;
    VariantList* add_list() ;
    Variant* add_variant() ;

    VariantList& operator=(const VariantList& list) ;

    void clear() ;
    inline bool empty() const {return (size_ == 0 || variants_ == NULL);}

    class iterator ;
    class SSPROTOAPI const_iterator { 
    public:
        const_iterator() ;
        const_iterator(const const_iterator& iter) ;
        const_iterator(const iterator& iter) ;
        const_iterator& operator=(const const_iterator& iter) ;
        const_iterator& operator=(const iterator& iter) ;

        bool operator==(const const_iterator& iter) const ;
        bool operator!=(const const_iterator& iter) const ;

        bool operator==(const iterator& iter) const ;
        bool operator!=(const iterator& iter) const ;

        const Variant * operator->() const;
        const Variant& operator*() const;
        const_iterator operator++() ;
        const_iterator operator++(int step) ;
        const_iterator operator--() ;
        const_iterator operator--(int step) ;

        friend class VariantList ;
    protected:
        Variant ** variants_ ;
        int index_ ;
        int size_ ;
    } ;
    
    class SSPROTOAPI iterator : public const_iterator{ 
    public:
        iterator() ;
        iterator& operator=(const iterator& iter) ;

        bool operator==(const iterator& iter) const ;
        bool operator!=(const iterator& iter) const ;
        Variant * operator->() ;
        /*
            如果var为空，会崩溃，所以在使用*之前，必须检查
        */
        Variant& operator*();
        iterator operator++() ;
        iterator operator++(int step) ;
        iterator operator--() ;
        iterator operator--(int step) ;
    } ;

    const_iterator begin() const ;
    iterator begin() ;

    const_iterator end() const ;
    iterator end() ;

    inline const Variant * operator[](size_t index) const 
    {
        if(variants_ == NULL || index >= capacity_)
            return NULL;

        return variants_[index] ;
    }

    inline Variant * operator[](size_t index)  
    {
        if(variants_ == NULL || index >= capacity_)
            return NULL;

        return variants_[index] ;
    }

    static const VariantList EMPTY ;
private:
    void copy(const VariantList& list) ;

    Variant ** variants_ ;
    size_t size_ ;
    size_t capacity_ ;

    bool extend() ;
} ;

/*
    替代map，作为message的基类
*/
class name_table ;
class VariantTable;
class SSPROTOAPI VariantMap{
public:
    VariantMap() ;
    //VariantMap(const VariantMap& map) ;
    virtual ~VariantMap() ;

    VariantMap& operator=(const VariantMap& map) ;

    void SetBool(const char *name, bool value);

    void SetUInt8(const char *name, uint8_t value);
    void SetUInt16(const char *name, uint16_t value);
    void SetUInt32(const char *name, uint32_t value);
    void SetUInt64(const char *name, uint64_t value);
    void SetInt8(const char *name, int8_t value);
    void SetInt16(const char *name, int16_t value);
    void SetInt32(const char *name, int32_t value);
    void SetInt64(const char *name, int64_t value);
    void SetFloat(const char *name, float value);
    void SetDouble(const char *name, double value);

    void SetString(const char *name, const std::string& value);
    void SetRaw(const char *name, const char *value, size_t size);
    void SetMap(const char * name , const VariantMap& map) ;
    void SetList(const char * name , const VariantList& list) ;

    /*
        这三个函数专门是为了提高性能，推荐使用。Add之后，会返回内部生成的类，然后直接在这个类上面操作
    */
    VariantMap* AddMap(const char *name) ;
    VariantList* AddList(const char *name) ;
	VariantTable* AddTable(const char* name);
    Variant* AddVariant(const char *name) ;


    //主要是解码的时候用
    Variant* AddVariant(const char *name , size_t nlen) ;



    bool GetBool(const char *name, bool &value) const;
    bool GetUInt8(const char *name, uint8_t &value) const;
    bool GetUInt16(const char *name, uint16_t &value) const;
    bool GetUInt32(const char *name, uint32_t &value) const;
    bool GetUInt64(const char *name, uint64_t &value) const;
    bool GetInt8(const char *name, int8_t &value) const;
    bool GetInt16(const char *name, int16_t &value) const;
    bool GetInt32(const char *name, int32_t &value) const;
    bool GetInt64(const char *name, int64_t &value) const;
    bool GetFloat(const char *name, float &value) const;
    bool GetDouble(const char *name, double &value) const;

    bool GetString(const char *name, std::string& value) const;
    bool GetRaw(const char *name, VariantRaw& value) const;
    bool GetMap(const char *name, VariantMap&value) const;
    bool GetList(const char * name , VariantList& value) const;

    /*
        内存引用模式，必须在Message析构之前，释放引用。
    */
    bool RefString(const char *name, const char *& value, size_t &size) const;
    bool RefRaw(const char *name, const void *& value, size_t &size) const;
    bool RefMap(const char *name, const VariantMap* &value) const;
    bool RefList(const char * name , const VariantList*& value) const;    

    Variant& operator[](const std::string& name) ;
    Variant& operator[](const char * name) ;

    class VariantMapItem{
    public:
        char * first ;
        Variant * second ;

        VariantMapItem() ;
        ~VariantMapItem() ;

        VariantMapItem(const char *name , Variant * data) ;
        void Value(const char * name , Variant * data) ;
        void Value(const char * name , size_t nlen , Variant * data) ;
        void Final() ;
    } ;

    typedef VariantMapItem Item ;

    class iterator ;
    class SSPROTOAPI const_iterator { 
    public:
        const_iterator() ;
        const_iterator& operator=(const const_iterator& iter) ;
        const_iterator(const iterator& iter) ;
        const_iterator& operator=(const iterator& iter) ;

        bool operator==(const const_iterator& iter) const ;
        bool operator!=(const const_iterator& iter) const ;

        bool operator==(const iterator& iter) const ;
        bool operator!=(const iterator& iter) const ;


        const Item* operator->() const;
        const_iterator operator++() ;
        const_iterator operator++(int step) ;
        const_iterator operator--() ;
        const_iterator operator--(int step) ;

        friend class VariantMap ;
    protected :
        Item * items_ ;
        int index_ ;
        int size_ ;
    } ;
    
    class SSPROTOAPI iterator : public const_iterator{ 
    public:
        iterator() ;
        iterator& operator=(const iterator& iter) ;

        bool operator==(const iterator& iter) const ;
        bool operator!=(const iterator& iter) const ;
        Item* operator->() ;
        iterator operator++() ;
        iterator operator++(int step) ;
        iterator operator--() ;
        iterator operator--(int step) ;
    } ;

    const_iterator begin() const ;
    iterator begin() ;

    const_iterator end() const ;
    iterator end() ;

    void clear() ;
    inline bool empty() const {return (size_ == 0) ;}

    /*
        提取每个字段的信息
    */
    inline size_t size() const {return size_ ;}
    const char * names(size_t index) const ;
    const Variant * values(size_t index) const ;
    Variant * values(size_t index) ;

    static const VariantMap EMPTY ;

    friend class Decoder ;

    void rebuild_name_table() ;


    /*
        兼容旧接口，可能被废弃，请勿使用
    */
    inline void setBool(const std::string& name, bool value) {SetBool(name.c_str() , value) ;}

    inline void setUint8(const std::string& name, uint8_t value) {SetUInt8(name.c_str() , value) ;}
    inline void setUint16(const std::string& name, uint16_t value){SetUInt16(name.c_str() , value) ;}
    inline void setUint32(const std::string& name, uint32_t value){SetUInt32(name.c_str() , value) ;}
    inline void setUint64(const std::string& name, uint64_t value){SetUInt64(name.c_str() , value) ;}
    inline void setInt8(const std::string& name, int8_t value){SetInt8(name.c_str() , value) ;}
    inline void setInt16(const std::string& name, int16_t value){SetInt16(name.c_str() , value) ;}
    inline void setInt32(const std::string& name, int32_t value){SetInt32(name.c_str() , value) ;}
    inline void setInt64(const std::string& name, int64_t value){SetInt64(name.c_str() , value) ;}
    inline void setFloat(const std::string& name, float value){SetFloat(name.c_str() , value) ;}
    inline void setDouble(const std::string& name, double value){SetDouble(name.c_str() , value) ;}

    inline void setString(const std::string& name, const std::string& value) {SetString(name.c_str() , value) ;}
    inline void setRaw(const std::string& name, const char *value, size_t size) {SetRaw(name.c_str() , value , size) ;}
    inline void setMap(const std::string& name , const VariantMap& map) {SetMap(name.c_str() , map) ;}
    inline void setList(const std::string& name , const VariantList& list) {SetList(name.c_str() , list) ;}


    inline bool getBool(const std::string& name, bool &value) const {return GetBool(name.c_str() , value) ;}
    inline bool getUint8(const std::string& name, uint8_t &value) const {return GetUInt8(name.c_str() , value) ;}
    inline bool getUint16(const std::string& name, uint16_t &value) const {return GetUInt16(name.c_str() , value) ;}
    inline bool getUint32(const std::string& name, uint32_t &value) const {return GetUInt32(name.c_str() , value) ;}
    inline bool getUint64(const std::string& name, uint64_t &value) const {return GetUInt64(name.c_str() , value) ;}
    inline bool getInt8(const std::string& name, int8_t &value) const {return GetInt8(name.c_str() , value) ;}
    inline bool getInt16(const std::string& name, int16_t &value) const {return GetInt16(name.c_str() , value) ;}
    inline bool getInt32(const std::string& name, int32_t &value) const {return GetInt32(name.c_str() , value) ;}
    inline bool getInt64(const std::string& name, int64_t &value) const {return GetInt64(name.c_str() , value) ;}
    inline bool getFloat(const std::string& name, float &value) const {return GetFloat(name.c_str() , value) ;}
    inline bool getDouble(const std::string& name, double &value) const {return GetDouble(name.c_str() , value) ;}

    inline bool getString(const std::string& name, std::string& value) const {return GetString(name.c_str() , value) ;}
    inline bool getRaw(const std::string& name, VariantRaw& value) const {return GetRaw(name.c_str() , value) ;}
    inline bool getMap(const std::string& name, VariantMap&value) const {return GetMap(name.c_str() , value) ;}
    inline bool getList(const std::string&  name , VariantList& value) const {return GetList(name.c_str() , value) ;}

	bool getValue(const char* name, const Variant*& var)const;
private:    
    Item * items_ ;
    size_t size_ ;
    size_t capacity_ ;

    mutable name_table * name_table_ ;      //只有在get的时候才生成
    mutable bool item_changed_ ;

    bool extend() ;
    void copy(const VariantMap& table) ;
    bool set_value(const char * name , Variant * var) ;
    bool get_value(const char * name , const Variant*& var) const ;

    bool set_value(const char * name , size_t nlen , Variant * var) ;
    bool get_value(const char * name , size_t nlen , const Variant*& var) const ;

    bool build_name_table() const;

    VariantMap(const VariantMap& map) ;
} ;

class TableCodec;
class FieldCollector;
class SSPROTOAPI VariantRecord{
public:
	bool setDouble(const std::string& name, double value);
	bool setString(const std::string& name, const std::string& value);
	bool setInt64(const std::string& name, int64_t value);
	bool setUint64(const std::string& name, uint64_t value);

	bool getDouble(const std::string& name, double& value)const;
	bool getString(const std::string& name, std::string& value)const;
	bool refString(const std::string& name, const char *& value, size_t &size)const;
	bool getInt64(const std::string& name, int64_t &value)const;
	bool getInt32(const std::string& name, int &value)const;

	bool getUint64(const std::string& name, uint64_t &value)const;


private:
	VariantRecord(TableCodec* table_codec, int row);
	FieldCollector* FindCollector(const std::string& name)const;
	FieldCollector* GetCollector(const std::string& name);
	friend class VariantTable;
	friend class VariantTableDecoder;

private:
	int row_;
	TableCodec* table_codec_;
};

class SSPROTOAPI VariantTable{
private:
	VariantTable(const VariantTable& vt);
public:
	VariantTable();
	~VariantTable();
	VariantTable& operator=(const VariantTable& table);
public:
	//添加一行
	VariantRecord* addRecord();
	//编码
	int encode()const;
	//编码后的长度
	int size()const;
	//编码后的内容
	const char* c_str()const;
public:
	TableCodec* table()const{ return table_codec_; }
private:
	void clear();
public:
	static const VariantTable EMPTY; //编码不做任何处理,size返回0,

private:
	typedef std::vector<VariantRecord*> Records;
	mutable unsigned char* buf_encoded_; //编码后的内容
	mutable int buf_encoded_len_;		 //编码后的长度
	Records* records_;					 //所有行(记录)
	TableCodec*	table_codec_;
};

class SSPROTOAPI VariantTableDecoder {
public:
	VariantTableDecoder();
	~VariantTableDecoder();

public:
	//解码
	bool decode(const char* data, size_t size);
	//获取有多少行
	int getRow();
	//获取有多少列
	int getCol();

	class SSPROTOAPI iterator {
	public:
		iterator(VariantTableDecoder* dec, int index);
		iterator& operator++();
		bool operator==(const iterator& iter) const;
		bool operator!=(const iterator& iter)const;
		VariantRecord* operator->();
		VariantRecord* operator*();
	private:
		iterator();
	private:
		VariantTableDecoder* dec_;
		int index_;
	};

	//迭代器起点
	iterator begin();
	//迭代器终点
	iterator end();

protected:
	VariantRecord* at(int index) { return records_->at(index); }

private:
	typedef std::vector<VariantRecord*> Records;
	Records* records_;	//所有行
	TableCodec* table_codec_;
};

class SSPROTOAPI Variant{
public:

    typedef union __st_variant_data 
    {
        int8_t          i8  ;
        uint8_t         u8  ;
        int16_t         i16 ;
        uint16_t        u16 ;
        int32_t         i32 ;
        uint32_t        u32 ;
        int64_t         i64 ;
        uint64_t        u64 ;
        bool            bv  ;
        float           f32 ;
        double          f64 ;
        char *          str ;
        void *          raw ;

        uint64_t        val ;
    } VariantData ;

    typedef enum 
    {

        VAR_UNKNOWN = 0 ,
        VAR_VOID = VAR_UNKNOWN ,

        VAR_BOOL    = 1 ,

        VAR_INT8    = 2 ,
        VAR_UINT8   = 3 ,

        VAR_INT16   = 4 ,
        VAR_UINT16  = 5 ,
        VAR_INT32   = 6 ,
        VAR_UINT32  = 7 ,
        VAR_INT64   = 8 ,
        VAR_UINT64  = 9 ,

        VAR_FLOAT   = 10 ,
        VAR_DOUBLE  = 11 ,

        VAR_STRING  = 12 ,        //str16
        VAR_RAW     = 13 ,        //vbin32

        VAR_MAP     = 14 ,        //map
        VAR_LIST    = 15 ,          //list
		VAR_TABLE	= 16 ,			//table
    } VarType ;

    VarType    Type ;
    uint32_t    Length ;
    VariantData Data ;

    typedef VariantMap Map ;
    typedef VariantList List ;
	typedef VariantTable Table;
    typedef VariantRaw Raw ;

    Variant()  ;
    Variant(const Variant& var) ;
    Variant(VarType type) ;

    Variant(bool val) ;
    Variant(int8_t val) ;
    Variant(uint8_t val) ;
    Variant(int16_t val) ;
    Variant(uint16_t val) ;
    Variant(int32_t val) ;
    Variant(uint32_t val) ;
    Variant(int64_t val) ;
    Variant(uint64_t val) ;

    Variant(float val) ;
    Variant(double val) ;

    Variant(const char * val) ;
    Variant(const std::string& val) ;
    Variant(const void * val , int len) ;

    Variant(const Map& map) ;
    Variant(const List& list) ;
    

    ~Variant()  ;

    void Clear() ;

    /*
        请注意，下面的Set和Get都有严格的类型匹配，比如bool类型Variant只能存取bool类型的值。
    */

    bool SetBool(bool val) ;
    bool SetInt8(int8_t val) ;
    bool SetUInt8(uint8_t val) ;
    bool SetInt16(int16_t val) ;
    bool SetUInt16(uint16_t val) ;
    bool SetInt32(int32_t val) ;
    bool SetUInt32(uint32_t val) ;
    bool SetInt64(int64_t val) ;
    bool SetUInt64(uint64_t val) ;

    bool SetFloat(float val) ;
    bool SetDouble(double val) ;

    bool SetString(const char * val) ;
    bool SetString(const std::string& val) ;
    bool SetRaw(const void * val , int len) ;

    bool SetMap(const Map& map) ;
    bool SetList(const List& list) ;

    bool GetBool(bool& val) const;
    bool GetInt8(int8_t& val) const;
    bool GetUInt8(uint8_t& val) const;
    bool GetInt16(int16_t& val) const;
    bool GetUInt16(uint16_t& val) const;
    bool GetInt32(int32_t& val) const;
    bool GetUInt32(uint32_t& val) const;
    bool GetInt64(int64_t& val) const;
    bool GetUInt64(uint64_t& val) const;

    bool GetFloat(float& val) const;
    bool GetDouble(double& val) const;

    bool GetString(std::string& val) const;
    bool GetRaw(void * val , size_t& len) const;
    bool GetRaw(Raw& val) const;

    bool GetMap(Map& map) const;
    bool GetList(List& list) const;

    /*  
        直接获取内部数据指针，不拷贝数据
    */
    bool RefString(const char *& str , size_t& len) const;
    bool RefRaw(const void *& val , size_t & len) const;

    bool RefMap(const Map *& map) const;
    bool RefList(const List *& list) const;
	bool RefTable(const Table *& table)const;


    Variant& operator=(bool val) ;
    Variant& operator=(int8_t val) ;
    Variant& operator=(uint8_t val) ;
    Variant& operator=(int16_t val) ;
    Variant& operator=(uint16_t val) ;
    Variant& operator=(int32_t val) ;
    Variant& operator=(uint32_t val) ;
    Variant& operator=(int64_t val) ;
    Variant& operator=(uint64_t val) ;

    Variant& operator=(float val) ;
    Variant& operator=(double val) ;

    Variant& operator=(const char * val) ;
    Variant& operator=(const std::string& val) ;

    Variant& operator=(const Raw& raw) ;

    Variant& operator=(const Map& map) ;
    Variant& operator=(const List& list) ;
    Variant& operator=(const Variant& var) ;

    operator bool() const ;

    operator int8_t() const ;
    operator uint8_t() const ;
    operator int16_t() const ;
    operator uint16_t() const ;
    operator int32_t() const ;
    operator uint32_t() const ;
    operator int64_t() const ;
    operator uint64_t() const ;

    operator float() const ;
    operator double() const ;

    /*
    //由于有长度，所以不需要输出。请使用RefXXX接口
    operator const char * () const ;        //string
    operator const void * () const ;        //raw
    */
    operator const Map& () const ;        //string
    operator const List& () const ;        //raw
	operator const Table& () const;

    void Assign(const Variant& var) ;

    static const Variant EMPTY ;
} ;


}
}

#endif  /** __SSPROTO_VARIANT_H */
